In this article we analyze the territorial income distribution in the city of Barcelona using data obtained from Barcelona open data repositorie: https://opendata-ajuntament.barcelona.cat/data/en/dataset/est-renda-familiar
import folium
import pandas as pd
import numpy as np
renta = pd.read_csv("2017_distribucio_territorial_renda_familiar.csv")
renta['NOM'] = renta['Nom_Barri']
renta['NOM'][renta['NOM']=='el Poble Sec'] = 'el Poble-sec'
renta
| Any | Codi_Districte | Nom_Districte | Codi_Barri | Nom_Barri | Població | Índex RFD Barcelona = 100 | NOM | |
|---|---|---|---|---|---|---|---|---|
| 0 | 2017 | 1 | Ciutat Vella | 1 | el Raval | 47986 | 71.2 | el Raval |
| 1 | 2017 | 1 | Ciutat Vella | 2 | el Barri Gòtic | 16240 | 106.1 | el Barri Gòtic |
| 2 | 2017 | 1 | Ciutat Vella | 3 | la Barceloneta | 15101 | 79.6 | la Barceloneta |
| 3 | 2017 | 1 | Ciutat Vella | 4 | Sant Pere, Santa Caterina i la Ribera | 22923 | 99.4 | Sant Pere, Santa Caterina i la Ribera |
| 4 | 2017 | 2 | Eixample | 5 | el Fort Pienc | 32048 | 106.5 | el Fort Pienc |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 68 | 2017 | 10 | Sant Martí | 69 | Diagonal Mar i el Front Marítim del Poblenou | 13710 | 150.1 | Diagonal Mar i el Front Marítim del Poblenou |
| 69 | 2017 | 10 | Sant Martí | 70 | el Besòs i el Maresme | 22893 | 60.4 | el Besòs i el Maresme |
| 70 | 2017 | 10 | Sant Martí | 71 | Provençals del Poblenou | 20649 | 102.3 | Provençals del Poblenou |
| 71 | 2017 | 10 | Sant Martí | 72 | Sant Martí de Provençals | 26187 | 67.4 | Sant Martí de Provençals |
| 72 | 2017 | 10 | Sant Martí | 73 | la Verneda i la Pau | 28725 | 57.0 | la Verneda i la Pau |
73 rows × 8 columns
https://opendata-ajuntament.barcelona.cat/data/en/dataset/20170706-districtes-barris provides json files with detail of administrative units of the city of Barcelona : districts, neighbourhoods, area of interest, basic statistical areas (AEB) and census areas. Today, Barcelona contains 10 different districts and 73 neighborhoods. In this article we employ neighborhood datas.
import json
with open('0301100100_UNITATS_ADM_POLIGONS.json', 'r') as f:
data_o = json.load(f)
data_o['features'] = data_o['features'][11:84]
for n in range(73):
data['features'][n]['properties']['Índex RFD Barcelona = 100']= renta['Índex RFD Barcelona = 100'].iloc[n]
According to https://opendata-ajuntament.barcelona.cat/ca/faqs , the coordinates in this json file use Spatial Reference System EPSG 25831, we need to transfom this system into EPSG 4326, which is the more standard reference system that we use nowadays. The simplest way to transform coordinates in Python is pyproj, i.e. the Python interface to PROJ.4 library.
from pyproj import Transformer
def trans(coordinate):
transformer = Transformer.from_crs("epsg:25831", "epsg:4326")
x2,y2 = transformer.transform(coordinate[0],coordinate[1])
return [y2, x2]
for n in range(73):
for i in range(len(data['features'][n]['geometry']['coordinates'][0])):
data['features'][n]['geometry']['coordinates'][0][i] = trans(data['features'][n]['geometry']['coordinates'][0][i])
if len(data['features'][n]['geometry']['coordinates'])>1:
for j in range(len(data['features'][n]['geometry']['coordinates'][1])):
data['features'][n]['geometry']['coordinates'][1][j] = trans(data['features'][n]['geometry']['coordinates'][1][j])
print(n)
import json
from copy import deepcopy
with open('bcn_neighborhood.json', 'r') as f:
data = json.load(f)
for n in range(73):
data['features'][n]['properties']['Índex RFD Barcelona = 100']= renta['Índex RFD Barcelona = 100'].iloc[n]
data1 = deepcopy(data)
data2 = deepcopy(data)
len(data1['features'])
73
len(data2['features'])
73
index1=0
index2=0
while index1< len(data1['features']):
if data1['features'][index1]['properties']['Índex RFD Barcelona = 100']>=100:
data1['features'].pop(index1)
else: index1+=1
while index2< len(data2['features']):
if data2['features'][index2]['properties']['Índex RFD Barcelona = 100']<100:
data2['features'].pop(index2)
else: index2+=1
BCN_map = folium.Map(location=[41.39, 2.17], zoom_start=12) # in location we must add the city's coordinates
choropleth = folium.Choropleth(geo_data=data, # GeoJson Coordinates
data=renta, # The table which contains the values we are analysing
columns=['NOM', 'Índex RFD Barcelona = 100'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='YlOrRd',
fill_opacity=0.7,
line_opacity=0.4,
legend_name='BCN income by neighborhood').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'Índex RFD Barcelona = 100'],
aliases=['Neiboorhood','RFD index']))
BCN_map
BCN_map.save("bcn_renta_2017.html")
BCN_map = folium.Map(location=[41.39, 2.17], zoom_start=12) # in location we must add the city's coordinates
choropleth = folium.Choropleth(geo_data=data1, # GeoJson Coordinates
data= renta[renta['Índex RFD Barcelona = 100']<100], # The table which contains the values we are analysing
columns=['NOM', 'Índex RFD Barcelona = 100'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='PuRd',
fill_opacity=0.7,
line_opacity=0.4,
legend_name='BCN income by neighborhood').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'Índex RFD Barcelona = 100'],
aliases=['Neiboorhood','RFD index']))
choropleth = folium.Choropleth(geo_data=data2, # GeoJson Coordinates
data=renta[renta['Índex RFD Barcelona = 100']>=100], # The table which contains the values we are analysing
columns=['NOM', 'Índex RFD Barcelona = 100'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='YlGn',
legend_name='BCN income by neighborhood').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'Índex RFD Barcelona = 100'],
aliases=['Neiboorhood','RFD index']))
BCN_map
import branca.colormap as cm
barcelona_map = folium.Map([41.40,2.17], zoom_start=12) # create a folium map
folium.GeoJson(data, style_function= lambda feature: {
'fillColor': '#ff0000' if feature['properties']['Índex RFD Barcelona = 100'] < 100 else '#008000'
}).add_to(barcelona_map)
barcelona_map
colorscale = cm.LinearColormap(colors=['red', 'green'], index=[0, 1])
barcelona_map.add_child(colorscale)
renta_07 = pd.read_csv("2007_distribucio_territorial_renda_familiar.csv")
renta_07 = renta_07.iloc[:-1]
renta_07['NOM'] = renta_07['Nom_Barri']
renta_07['NOM'][renta_07['NOM']=='el Poble Sec'] = 'el Poble-sec'
renta_07['Índex RFD Barcelona = 100'] = renta_07['Índex RFD Barcelona = 100'].astype('float64')
renta_07['RFD change'] = (renta['Índex RFD Barcelona = 100']-renta_07['Índex RFD Barcelona = 100'])/renta_07['Índex RFD Barcelona = 100']*100
renta_07
/var/folders/03/gv3k10bj7135k97m7mbkq26h0000gn/T/ipykernel_4851/2225712002.py:4: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy renta_07['NOM'][renta_07['NOM']=='el Poble Sec'] = 'el Poble-sec'
| Any | Codi_Districte | Nom_Districte | Codi_Barri | Nom_Barri | Població | Índex RFD Barcelona = 100 | NOM | RFD change | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 2007 | 1 | Ciutat Vella | 1 | el Raval | 46595 | 64.7 | el Raval | 10.046368 |
| 1 | 2007 | 1 | Ciutat Vella | 2 | el Barri Gòtic | 27946 | 86.5 | el Barri Gòtic | 22.658960 |
| 2 | 2007 | 1 | Ciutat Vella | 3 | la Barceloneta | 15921 | 66.7 | la Barceloneta | 19.340330 |
| 3 | 2007 | 1 | Ciutat Vella | 4 | Sant Pere, Santa Caterina i la Ribera | 22572 | 80.2 | Sant Pere, Santa Caterina i la Ribera | 23.940150 |
| 4 | 2007 | 2 | Eixample | 5 | el Fort Pienc | 31521 | 107.9 | el Fort Pienc | -1.297498 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 68 | 2007 | 10 | Sant Martí | 69 | Diagonal Mar i el Front Marítim del Poblenou | 9775 | 101.1 | Diagonal Mar i el Front Marítim del Poblenou | 48.466864 |
| 69 | 2007 | 10 | Sant Martí | 70 | el Besòs i el Maresme | 22652 | 61.7 | el Besòs i el Maresme | -2.106969 |
| 70 | 2007 | 10 | Sant Martí | 71 | Provençals del Poblenou | 18731 | 85.7 | Provençals del Poblenou | 19.369895 |
| 71 | 2007 | 10 | Sant Martí | 72 | Sant Martí de Provençals | 26261 | 81.5 | Sant Martí de Provençals | -17.300613 |
| 72 | 2007 | 10 | Sant Martí | 73 | la Verneda i la Pau | 29452 | 74.8 | la Verneda i la Pau | -23.796791 |
73 rows × 9 columns
BCN_map = folium.Map(location=[41.39, 2.17], zoom_start=12) # in location we must add the city's coordinates
choropleth = folium.Choropleth(geo_data=data, # GeoJson Coordinates
data=renta_07, # The table which contains the values we are analysing
columns=['NOM', 'Índex RFD Barcelona = 100'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='YlOrRd',
fill_opacity=0.7,
line_opacity=0.4,
legend_name='BCN income by neighborhood').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'Índex RFD Barcelona = 100'],
aliases=['Neiboorhood','RFD index']))
BCN_map
type(data['features'][n]['properties']['Població'])
numpy.int64
for n in range(73):
data['features'][n]['properties']['Població']= int(renta_07['Població'].iloc[n])
BCN_map = folium.Map(location=[41.39, 2.17], zoom_start=12) # in location we must add the city's coordinates
choropleth = folium.Choropleth(geo_data=data, # GeoJson Coordinates
data=renta_07, # The table which contains the values we are analysing
columns=['NOM', 'Població'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='YlOrRd',
fill_opacity=0.7,
line_opacity=0.4,
legend_name='BCN population').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'Població'],
aliases=['Neiboorhood','Population']))
BCN_map
for n in range(73):
data['features'][n]['properties']['RFD change']= renta_07['RFD change'].iloc[n]
BCN_map = folium.Map(location=[41.39, 2.17], zoom_start=12) # in location we must add the city's coordinates
choropleth = folium.Choropleth(geo_data=data, # GeoJson Coordinates
data=renta_07, # The table which contains the values we are analysing
columns=['NOM', 'RFD change'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='YlOrRd',
fill_opacity=0.7,
line_opacity=0.4,
legend_name='BCN income by neighborhood').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'RFD change'],
aliases=['Neiboorhood','RFD change %']))
BCN_map
data3 = deepcopy(data)
data4 = deepcopy(data)
index1=0
index2=0
while index1< len(data3['features']):
if data3['features'][index1]['properties']['RFD change']>=0:
data3['features'].pop(index1)
else: index1+=1
while index2< len(data4['features']):
if data4['features'][index2]['properties']['RFD change']<0:
data4['features'].pop(index2)
else: index2+=1
BCN_map = folium.Map(location=[41.39, 2.17], zoom_start=12) # in location we must add the city's coordinates
choropleth = folium.Choropleth(geo_data=data3, # GeoJson Coordinates
data=renta_07[renta_07['RFD change']<0], # The table which contains the values we are analysing
columns=['NOM', 'RFD change'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='PuRd',
fill_opacity=0.7,
line_opacity=0.4,
legend_name='BCN income by neighborhood').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'RFD change'],
aliases=['Neiboorhood','RFD change %']))
choropleth = folium.Choropleth(geo_data=data4, # GeoJson Coordinates
data=renta_07[renta_07['RFD change']>=0], # The table which contains the values we are analysing
columns=['NOM', 'RFD change'],
key_on='feature.properties.NOM', # We chose the key we need in the GeoJson file
fill_color='YlGn',
legend_name='BCN income by neighborhood').add_to(BCN_map)
choropleth.geojson.add_child(folium.features.GeoJsonTooltip(['NOM', 'RFD change'],
aliases=['Neiboorhood','RFD change %']))
BCN_map